package org.activemonitoring.harvesters;

import java.util.List;
import java.util.Random;

import org.activemonitoring.datastore.dao.DataStoreDao;
import org.activemonitoring.datastore.entity.MeasureEntity;
import org.apache.log4j.Logger;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import static org.junit.Assert.assertEquals;

public class HarvesterImplCase {

    private static final Logger logger = Logger.getLogger(HarvesterImplCase.class);

    private ClassPathXmlApplicationContext applicationContext;
    private HarvesterImpl harvester;

    private DataStoreDao dataStoreDao;

    @Before
    public void setUp() {
        this.applicationContext = new ClassPathXmlApplicationContext(new String[] {
                "applicationContext-harvesters.xml", "applicationContext-datastore.xml",
                "applicationContext-test-directjava.xml" });
        this.applicationContext.start();
        this.dataStoreDao = this.applicationContext.getBean("dataStoreDao", DataStoreDao.class);
        this.harvester = this.applicationContext.getBean("harvester", HarvesterImpl.class);
        this.harvester.setDataStore(this.dataStoreDao);
    }

    @Test
    public void testMonitoring() throws Exception {
        Runnable runner = new Runnable() {
            @Override
            public void run() {
                try {
                    Random random = new Random();
                    logger.info("Starting measure creation");
                    for (int i = 0; i < 100; i++) {
                        MeasureBuilder measure = HarvesterImplCase.this.harvester.start("fakeModule",
                                "fakeMeasure.step1");
                        Thread.sleep(random.nextInt(10) * 10L);
                        measure.stop();
                        // Thread.sleep(50L);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        Thread thread1 = new Thread(runner, "Runner1");
        thread1.start();
        Thread thread2 = new Thread(runner, "Runner2");
        thread2.start();
        thread1.join();
        thread2.join();
        logger.info("Ending measure creation");
        logger.info("Waiting for Harvester to send last measures");
        // Waiting the configured timeout
        Thread.sleep(5000L);
        List<MeasureEntity> measures = this.dataStoreDao.getMeasures();
        assertEquals(200, measures.size());
        long totalTime = 0;
        for (MeasureEntity measureEntity : measures) {
            totalTime += measureEntity.getElapsedTime();
        }
        logger.info("Average elapsed time: " + totalTime / measures.size() + " ms");
    }

    @After
    public void tearDown() {
        this.dataStoreDao.clear();
        this.applicationContext.stop();
    }
}
